<!--#include file="pay.alipay.core.asp"-->
<%
'支付宝接口集成
'接口名称：标准双接口/即时到帐接口/纯担保交易接口
'代码版本：3.3
'------------------------
'KnifeCMS集成
'集成人：linx
'集成时间：2012-12-30

Dim GATEWAY_NEW : GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?"
'支付宝消息验证地址
Dim HTTPS_VERIFY_URL : HTTPS_VERIFY_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&"

Class LibPayment_Alipay
    Private Pv_Rs,Pv_Action,Pv_HaveTreated,Pv_InterFaceType,Pv_PaymentID,Pv_PaymentName,Pv_PayMethod,Pv_Fee,Pv_Poundage,Pv_OrderID,Pv_Result
	Private Pv_AliTradeNo,Pv_Final_Amount,Pv_IsOrderExist
	Private Pv_TradeFee
	
	'==alipayto==
	Public partner,key,input_charset,sign_type
	Private payment_type,notify_url,return_url,seller_email,out_trade_no,subject,total_fee,body,show_url,anti_phishing_key,exter_invoke_ip
	Private sParaTemp,sHtml
	'==担保==
	Private price,quantity,logistics_fee,logistics_type,logistics_payment,receive_name,receive_address,receive_zip,receive_phone,receive_mobile
	'==notify/return=
	Private trade_no,trade_status
	Private sVerifyResult
	'========
	
	Private Sub Class_Initialize()
		input_charset = "utf-8"'字符编码格式
		sign_type     = "MD5"'签名方式
		partner       = ""'合作身份者ID，以2088开头的16位纯数字
		key   		  = ""'安全检验码，以数字和字母组成的32位字符
		seller_email  = ""'签约支付宝账号(卖家支付宝帐户)
		'========
		Pv_IsOrderExist = False
		Pv_HaveTreated  = False
	End Sub
	Private Sub Class_Terminate()
	End Sub
	
	Public Property Let Action(ByVal BV_String)
		Pv_Action = BV_String
	End Property
	Public Property Let PaymentID(ByVal BV_String)
		Pv_PaymentID = BV_String
	End Property
	Public Property Let OrderID(ByVal BV_String)
		Pv_OrderID = BV_String
	End Property
	
	Public Sub Init()
		Dim Fn_Currency
		'创建支付数据进入支付宝支付页面
		
		If Pv_Action = "alipayto" Then
			'取得支付宝配置信息
			Call Config()
			
			Select Case Pv_InterFaceType
			Case 1,"create_direct_pay_by_user"'即时到账交易接口
				'取得订单信息
				Call GetOrderInfo()
				
				'支付类型[必填，不能修改]
				payment_type = "1"
				
				'服务器异步通知页面路径(需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/)
				notify_url = SiteURL & SystemPath &"plugins/payment/pay.alipay.notify.asp"
					
				'页面跳转同步通知页面路径(需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/)
				return_url = SiteURL & SystemPath &"plugins/payment/pay.alipay.return.asp"
			
				'卖家支付宝帐户[必填]
				'seller_email = seller_email
		
				'生成交易单号(商户订单号)
				out_trade_no = OS.CreatePayTradeNo()
		
				'订单名称[必填]
				subject      = SiteName &" 订单"&Pv_OrderID&""
	
				'付款金额[必填]
				total_fee    = Pv_Final_Amount
		
				'订单描述
				body         = SiteName &" 订单"&Pv_OrderID&""
				
				'商品展示地址(需以http://开头的完整路径，例如：http://www.xxx.com/myorder.htm)
				show_url     = ""
				
				'防钓鱼时间戳(若要使用请调用类文件submit中的query_timestamp函数)
				anti_phishing_key = ""
				
				'客户端的IP地址(非局域网的外网IP地址，如：221.0.0.1)
				exter_invoke_ip   = ""
				
				'构造请求参数数组
				sParaTemp = Array("service=create_direct_pay_by_user","partner="&partner,"_input_charset="&input_charset,"payment_type="&payment_type,"notify_url="&notify_url,"return_url="&return_url,"seller_email="&seller_email,"out_trade_no="&out_trade_no,"subject="&subject,"total_fee="&total_fee,"body="&body,"show_url="&show_url,"anti_phishing_key="&anti_phishing_key,"exter_invoke_ip="&exter_invoke_ip  )
				'建立请求
				sHtml = BuildRequestForm(sParaTemp,"get",Lang_Confirm)
				
				'KnifeCMS创建支付记录
				Fn_Currency = "CNY"
				Pv_Result   = KnifeCMS.DB.AddRecord(DBTable_PayTradeLog,Array("TradeType:orderpay","TradeNo:"& out_trade_no,"Currency:"& Fn_Currency,"TradeFee:"& total_fee,"PaymentID:"& Pv_PaymentID,"PaymentName:"& Pv_PaymentName,"OrderID:"& Pv_OrderID,"StartTime:"& SysTime,"MemberID:"& UserID,"Remarks:","Status:ready","CreateType:auto","IP:"& KnifeCMS.GetClientIP,"Recycle:0"))
				'创建成功则提交记录
				If Pv_Result Then
					Echo sHtml
				Else
					Echo "K"&"n"&"i"&"f"&"e"&"C"&"MS: Crearte pay trade log error!"
				End If
			Case 0,"trade_create_by_buyer",2,"create_partner_trade_by_buyer"
			'0:标准双接口
			'2:纯担保交易接口
			
				'取得订单信息
				Call GetOrderInfo()
				
				'支付类型[必填，不能修改]
				payment_type = "1"
				
				'服务器异步通知页面路径(需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/)
				notify_url = SiteURL & SystemPath &"plugins/payment/pay.alipay.notify.asp"
					
				'页面跳转同步通知页面路径(需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/)
				return_url = SiteURL & SystemPath &"plugins/payment/pay.alipay.return.asp"
			
				'卖家支付宝帐户[必填]
				'seller_email = seller_email
		
				'生成交易单号(商户订单号)
				out_trade_no = OS.CreatePayTradeNo()
		
				'订单名称[必填]
				subject      = SiteName &" 订单"&Pv_OrderID&""
	
				'付款金额[必填]
				price    = Pv_Final_Amount

				'商品数量[必填，建议默认为1，不改变值，把一次交易看成是一次下订单而非购买一件商品]
				quantity = "1"

				'物流费用[必填，即运费]
				logistics_fee = "0.00"
				
				'物流类型[必填，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）]
				logistics_type = "EXPRESS"

				'物流支付方式[必填，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）]
				logistics_payment = "SELLER_PAY"
		
				'订单描述
				body         = SiteName &" 订单"&Pv_OrderID&""
				
				'商品展示地址(需以http://开头的完整路径，例如：http://www.xxx.com/myorder.htm)
				show_url     = ""
				
				'收货人姓名[如：张三]
				receive_name = ""
		
				'收货人地址[如：XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号]
				receive_address = ""
		
				'收货人邮编[如：123456]
				receive_zip = ""
		
				'收货人电话号码[如：0571-88158090]
				receive_phone = ""
		
				'收货人手机号码[如：13312341234]
				receive_mobile = ""
				
				'构造请求参数数组
				If Pv_InterFaceType=0 Or Pv_InterFaceType="trade_create_by_buyer" Then
				sParaTemp = Array("service=trade_create_by_buyer","partner="&partner,"_input_charset="&input_charset  ,"payment_type="&payment_type   ,"notify_url="&notify_url   ,"return_url="&return_url   ,"seller_email="&seller_email   ,"out_trade_no="&out_trade_no   ,"subject="&subject   ,"price="&price   ,"quantity="&quantity   ,"logistics_fee="&logistics_fee   ,"logistics_type="&logistics_type   ,"logistics_payment="&logistics_payment   ,"body="&body   ,"show_url="&show_url   ,"receive_name="&receive_name   ,"receive_address="&receive_address   ,"receive_zip="&receive_zip   ,"receive_phone="&receive_phone   ,"receive_mobile="&receive_mobile  )
				Else
				sParaTemp = Array("service=create_partner_trade_by_buyer","partner="&partner,"_input_charset="&input_charset  ,"payment_type="&payment_type   ,"notify_url="&notify_url   ,"return_url="&return_url   ,"seller_email="&seller_email   ,"out_trade_no="&out_trade_no   ,"subject="&subject   ,"price="&price   ,"quantity="&quantity   ,"logistics_fee="&logistics_fee   ,"logistics_type="&logistics_type   ,"logistics_payment="&logistics_payment   ,"body="&body   ,"show_url="&show_url   ,"receive_name="&receive_name   ,"receive_address="&receive_address   ,"receive_zip="&receive_zip   ,"receive_phone="&receive_phone   ,"receive_mobile="&receive_mobile)
				End If
				'建立请求
				sHtml = BuildRequestForm(sParaTemp,"get",Lang_Confirm)
				
				'KnifeCMS创建支付记录
				Fn_Currency = "CNY"
				Pv_Result   = KnifeCMS.DB.AddRecord(DBTable_PayTradeLog,Array("TradeType:orderpay","TradeNo:"& out_trade_no,"Currency:"& Fn_Currency,"TradeFee:"& price,"PaymentID:"& Pv_PaymentID,"PaymentName:"& Pv_PaymentName,"OrderID:"& Pv_OrderID,"StartTime:"& SysTime,"MemberID:"& UserID,"Remarks:","Status:ready","CreateType:auto","IP:"& KnifeCMS.GetClientIP,"Recycle:0"))
				'创建成功则提交记录
				If Pv_Result Then
					Echo sHtml
				Else
					Echo "Kn"&"i"&"f"&"e"&"C"&"M"&"S: Crearte pay trade log error!"
				End If
			End Select
		'支付宝主动通知调用的页面（服务器异步通知页面）
		ElseIf Pv_Action = "notify" Then
			'商户订单号
			out_trade_no = KnifeCMS.Data.Left(KnifeCMS.Data.RegReplace(KnifeCMS.GetForm("post","out_trade_no"),"[^0-9]",""),20)
			'支付宝交易号
			trade_no     = KnifeCMS.Data.Left(KnifeCMS.Data.RegReplace(KnifeCMS.GetForm("post","trade_no"),"[^0-9a-zA-Z]",""),20)
			'交易状态
			trade_status = KnifeCMS.GetForm("post","trade_status")
			
			'判断返回的是否是合法的商户订单号
			'或合法的则获取订单信息
			Set Pv_Rs = KnifeCMS.DB.GetRecord(DBTable_PayTradeLog &":TradeFee,PaymentID,PaymentName,OrderID",Array("TradeNo:"& out_trade_no),"")
			If Not(Pv_Rs.Eof) Then
				Pv_PaymentID   = Pv_Rs("PaymentID")
				Pv_PaymentName = Pv_Rs("PaymentName")
				Pv_TradeFee    = Pv_Rs("TradeFee")
				Pv_OrderID     = Pv_Rs("OrderID")
				IsContentExist = True
			Else
				IsContentExist = False
			End If
			KnifeCMS.DB.CloseRs Pv_Rs
			
			If IsContentExist Then
				Call Config()
				'计算得出通知验证结果
				
				sVerifyResult = VerifyNotify()
				'验证成功
				If sVerifyResult Then
				
					Select Case Pv_InterFaceType
					Case 1,"create_direct_pay_by_user"'即时到账交易接口
						If trade_status = "TRADE_FINISHED" Or trade_status = "TRADE_SUCCESS" Then
						'TRADE_FINISHED与TRADE_SUCCESS都代表交易成功，区别：(普通即时到帐状态下返回TRADE_FINISHED),(高级即时到帐状态下返回TRADE_SUCCESS)
							If KnifeCMS.DB.GetFieldByArrayField(DBTable_PayTradeLog,"Status",Array("TradeNo:"& out_trade_no))<>"success" Then
								Pv_HaveTreated = False
								'更新交易记录状态为success
								Pv_Result = KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:success","IP:"& KnifeCMS.GetClientIP),Array("TradeNo:"& out_trade_no))
								If Pv_Result Then
									'创建订单支付单记录|创建订单日志记录
									Call CreatePaymentBillAndOrderLog()
									'更新订单支付状态
									Call UpdateOrderStatus(Pv_OrderID)
									Echo "success"
								End If
							Else
								Echo "success"
							End If
						Else
						'返回其他状态
							'更新交易记录状态为failed
							Call KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:failed"),Array("TradeNo:"& out_trade_no))
							Echo "success"
						End If
					Case 0,"trade_create_by_buyer",2,"create_partner_trade_by_buyer"
					'0:标准双接口
					'2:纯担保交易接口
						If trade_status = "WAIT_BUYER_PAY" Then
						'该判断表示买家已在支付宝交易管理中产生了交易记录，但没有付款
							'更新交易记录状态为waitpay
							Call KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:waitpay"),Array("TradeNo:"& out_trade_no))
							Echo "success"
						ElseIf trade_status = "WAIT_SELLER_SEND_GOODS" Or trade_status = "WAIT_BUYER_CONFIRM_GOODS" Or trade_status = "TRADE_FINISHED" Then
						'WAIT_BUYER_CONFIRM_GOODS : 该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货
						'WAIT_BUYER_CONFIRM_GOODS : 该判断表示卖家已经发了货，但买家还没有做确认收货的操作
						'TRADE_FINISHED           : 该判断表示买家已经确认收货，这笔交易完成
							If KnifeCMS.DB.GetFieldByArrayField(DBTable_PayTradeLog,"Status",Array("TradeNo:"& out_trade_no))<>"success" Then
								Pv_HaveTreated = False
								'更新交易记录状态为success
								Pv_Result = KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:success","IP:"& KnifeCMS.GetClientIP),Array("TradeNo:"& out_trade_no))
								If Pv_Result Then
									'创建订单支付单记录|创建订单日志记录
									Call CreatePaymentBillAndOrderLog()
									'更新订单支付状态
									Call UpdateOrderStatus(Pv_OrderID)
									Echo "success"
								End If
							Else
								Echo "success"
							End If
						Else
						'返回其他状态
							'更新交易记录状态为failed
							Call KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:failed"),Array("TradeNo:"& out_trade_no))
							Echo "success"
						End If
					End Select
				Else
					'验证失败
					Echo "fail"
				End If
			Else
				'支付交易记录不存在(即传递过来的是非法构建的数据)
				Echo "fail"
			End If
		'付完款后跳转的页面（页面跳转同步通知页面）
		ElseIf Pv_Action = "return" Then
			'商户订单号
			out_trade_no = KnifeCMS.Data.Left(KnifeCMS.Data.RegReplace(KnifeCMS.GetForm("get","out_trade_no"),"[^0-9]",""),20)
			'支付宝交易号
			trade_no     = KnifeCMS.Data.Left(KnifeCMS.Data.RegReplace(KnifeCMS.GetForm("get","trade_no"),"[^0-9a-zA-Z]",""),20)
			'交易状态
			trade_status = KnifeCMS.GetForm("get","trade_status")
			
			'判断返回的是否是合法的商户订单号
			'或合法的则获取订单信息
			Set Pv_Rs = KnifeCMS.DB.GetRecord(DBTable_PayTradeLog &":TradeFee,PaymentID,PaymentName,OrderID",Array("TradeNo:"& out_trade_no),"")
			If Not(Pv_Rs.Eof) Then
				Pv_PaymentID   = Pv_Rs("PaymentID")
				Pv_PaymentName = Pv_Rs("PaymentName")
				Pv_TradeFee    = Pv_Rs("TradeFee")
				Pv_OrderID     = Pv_Rs("OrderID")
				IsContentExist = True
			Else
				IsContentExist = False
			End If
			KnifeCMS.DB.CloseRs Pv_Rs

			If IsContentExist Then
				Call Config()
				'计算得出通知验证结果
				sVerifyResult = VerifyReturn()
				'验证成功
				If sVerifyResult Then
					Select Case Pv_InterFaceType
					Case 1,"create_direct_pay_by_user"'即时到账交易接口
						If trade_status = "TRADE_FINISHED" Or trade_status = "TRADE_SUCCESS" Then
						'TRADE_FINISHED与TRADE_SUCCESS都代表交易成功，区别：(普通即时到帐状态下返回TRADE_FINISHED),(高级即时到帐状态下返回TRADE_SUCCESS)
							If KnifeCMS.DB.GetFieldByArrayField(DBTable_PayTradeLog,"Status",Array("TradeNo:"& out_trade_no))<>"success" Then
								Pv_HaveTreated = False
								'更新交易记录状态为success
								Pv_Result = KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:success","IP:"& KnifeCMS.GetClientIP),Array("TradeNo:"& out_trade_no))
								If Pv_Result Then
									'创建订单支付单记录|创建订单日志记录
									Call CreatePaymentBillAndOrderLog()
									'更新订单支付状态
									Call UpdateOrderStatus(Pv_OrderID)
								End If
								Call PrintSuccessMessage()
							Else
								Call PrintSuccessMessage()
							End If
						'返回其他状态
						Else
							'更新交易记录状态为failed
							Call KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:failed"),Array("TradeNo:"& out_trade_no))
							Call PrintFailMessage()
						End If
					Case 0,"trade_create_by_buyer",2,"create_partner_trade_by_buyer"
					'0:标准双接口
					'2:纯担保交易接口
					    If trade_status = "WAIT_SELLER_SEND_GOODS" Or trade_status = "TRADE_FINISHED" Then
						'WAIT_SELLER_SEND_GOODS : 该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货
						'TRADE_FINISHED         : 该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功(即时到帐)
							If KnifeCMS.DB.GetFieldByArrayField(DBTable_PayTradeLog,"Status",Array("TradeNo:"& out_trade_no))<>"success" Then
								Pv_HaveTreated = False
								'更新交易记录状态为success
								Pv_Result = KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:success","IP:"& KnifeCMS.GetClientIP),Array("TradeNo:"& out_trade_no))
								If Pv_Result Then
									'创建订单支付单记录|创建订单日志记录
									Call CreatePaymentBillAndOrderLog()
									'更新订单支付状态
									Call UpdateOrderStatus(Pv_OrderID)
								End If
								Call PrintSuccessMessage()
							Else
								Call PrintSuccessMessage()
							End If
						'返回其他状态
						Else
							'更新交易记录状态为failed
							Call KnifeCMS.DB.UpdateRecord(DBTable_PayTradeLog,Array("EndTime:"& SysTime,"BankTradeNo:"& trade_no,"Status:failed"),Array("TradeNo:"& out_trade_no))
							Call PrintFailMessage()
						End If
					End Select
				Else
					'验证失败
					Call PrintFailMessage(Lang_VerifyFail)
				End If
			Else
				'支付交易记录不存在(即传递过来的是非法构建的数据)
				Call PrintFailMessage(Lang_PayTradeLogNotExist)
			End If
		End If
	End Sub
	
	'取得支付宝配置信息
	Public Sub Config()
		Dim Fn_Rs,Fn_Config
		Set Fn_Rs = KnifeCMS.DB.GetRecord(DBTable_Payments &":Config,PaymentName,PayMethod,Fee",Array("ID:"& Pv_PaymentID,"PayType:alipay"),"")
		If Not(Fn_Rs.Eof) Then
			Fn_Config      = Fn_Rs("Config")
			Pv_PaymentName = Fn_Rs("PaymentName")
			Pv_PayMethod   = Fn_Rs("PayMethod")
		    Pv_Fee         = Fn_Rs("Fee")
		End If
		KnifeCMS.DB.CloseRs Fn_Rs
		seller_email     = KnifeCMS.GetConfigParameter(Fn_Config,"SellerEmail")
		partner          = KnifeCMS.GetConfigParameter(Fn_Config,"Partner")
		key              = KnifeCMS.GetConfigParameter(Fn_Config,"PrivateKey")
		Pv_InterFaceType = KnifeCMS.GetConfigParameter(Fn_Config,"InterFaceType")
	End Sub
	
	'取得订单信息
	Public Sub GetOrderInfo()
		Dim Fn_Rs
		Set Fn_Rs = KnifeCMS.DB.GetRecord(DBTable_Order &":Final_Amount",Array("OrderID:"& Pv_OrderID,"Recycle:0"),"")
		If Not(Fn_Rs.Eof) Then
			Pv_IsOrderExist = True
			Pv_Final_Amount = Fn_Rs(0)
		End If
		KnifeCMS.DB.CloseRs Fn_Rs
	End Sub
	
	'创建订单支付单记录|创建订单日志记录
	Private Function CreatePaymentBillAndOrderLog()
		Dim Fn_Result : Fn_Result = 0
		Dim Fn_BillID,Fn_OrderID,Fn_UserID,Fn_Username,Fn_Bank,Fn_Account,Fn_PayAccount,Fn_Currency,Fn_Money,Fn_PayCost,Fn_CurMoney,Fn_PayType,Fn_PaymentID,Fn_PaymentName,Fn_OperaterID,Fn_IP,Fn_TBegin,Fn_TEnd,Fn_Status,Fn_Remarks,Fn_Disabled,Fn_TradeNo
		Dim Fn_LogText
		SysID         = KnifeCMS.CreateSysID
		Fn_BillID     = OS.CreateBillID("paymentbill")
		Fn_OrderID    = Pv_OrderID
		Fn_UserID     = KnifeCMS.DB.GetFieldByArrayField(DBTable_Order,"UserID",Array("OrderID:"& Fn_OrderID))'UserID
		Fn_Username   = KnifeCMS.DB.GetFieldByArrayField(DBTable_Members,"Username",Array("ID:"& Fn_UserID))'会员用户名
		Fn_Bank       = Lang_Bank(1)'收款银行
		Fn_Account    = seller_email'收款账号
		Fn_PayAccount = ""
		Fn_Currency   = "CNY"
		Fn_Money      = Pv_TradeFee
		Fn_PayCost    = 0
		Fn_CurMoney   = Fn_Money
		Fn_PayType    = "alipay"
		Fn_PaymentID  = Pv_PaymentID
		Fn_PaymentName= Pv_PaymentName
		Fn_OperaterID = 0
		Fn_IP         = KnifeCMS.GetClientIP()
		Fn_TBegin     = SysTime
		Fn_TEnd       = SysTime
		Fn_Status     = "success"
		Fn_Remarks    = ""
		Fn_Disabled   = 0
		Fn_TradeNo    = out_trade_no
		'添加订单支付记录
		Fn_Result = KnifeCMS.DB.AddRecord(DBTable_PaymentBill,Array("SysID:"& SysID,"BillID:"& Fn_BillID,"OrderID:"& Fn_OrderID,"UserID:"& Fn_UserID,"Bank:"& Fn_Bank,"Account:"& Fn_Account,"PayAccount:"& Fn_PayAccount,"Currency:"& Fn_Currency,"Money:"& Fn_Money,"PayCost:"& Fn_PayCost,"CurMoney:"& Fn_CurMoney,"PayType:"& Fn_PayType,"PaymentID:"& Fn_PaymentID,"PaymentName:"& Fn_PaymentName,"OperaterID:"& Fn_OperaterID,"IP:"& Fn_IP,"TBegin:"& Fn_TBegin,"TEnd:"& Fn_TEnd,"Status:"& Fn_Status,"Remarks:"& Fn_Remarks,"Disabled:"& Fn_Disabled,"TradeNo:"& Fn_TradeNo,"Recycle:0"))
		If Fn_Result Then
			Fn_LogText = Lang_OrderLogText(1) & "{[支付单号:"& Fn_BillID &"][支付金额:"& MoneySb & KnifeCMS.Data.FormatCurrency(Fn_Money) &"]}"
			'添加订单记录
			Call KnifeCMS.DB.AddRecord(DBTable_OrderLog,Array("OrderID:"& Pv_OrderID,"UserID:"& Fn_UserID,"SysUserID:NULL","OperaterName:"& Fn_Username,"LogText:" & Fn_LogText,"AddTime:"& SysTime,"BeHavior:"& Lang_OrderLogBehavior(1),"Result:success"))
		End If
		CreatePaymentBillAndOrderLog = Fn_Result
	End Function
	
	'更新订单支付状态和已支付金额
	Private Function UpdateOrderStatus(ByVal BV_OrderID)
		Dim Fn_Result : Fn_Result = 0
		Dim Fn_Rs,Fn_TempMoney,Fn_Final_Amount,Fn_Payed,Fn_PayStatus
		Fn_Final_Amount = 0
		Fn_TempMoney    = 0
		Set Fn_Rs = KnifeCMS.DB.GetRecord(DBTable_Order &":Final_Amount,Payed",Array("OrderID:"& BV_OrderID),"")
		If Not(Fn_Rs.Eof) Then
			Fn_Final_Amount = Fn_Rs(0)
			Fn_Payed        = Fn_Rs(1)
			Fn_TempMoney = KnifeCMS.Data.FormatDouble(Fn_Final_Amount) - KnifeCMS.Data.FormatDouble(Fn_Payed)
			If Pv_TradeFee < Fn_TempMoney Then
				Fn_PayStatus = 3
			Else
				Fn_PayStatus = 1
			End If
			Fn_Result = KnifeCMS.DB.UpdateRecord(DBTable_Order,"PayStatus="& Fn_PayStatus &",Payed=Payed+"& Pv_TradeFee,Array("OrderID:"& BV_OrderID))
			'If Fn_TempMoney>0 Then
'				Call KnifeCMS.DB.UpdateRecord(DBTable_Order,"Payed=Payed+"& Pv_TradeFee,Array("OrderID:"& BV_OrderID))
'			End If
		End If
		KnifeCMS.DB.CloseRs Fn_Rs
		UpdateOrderStatus = Fn_Result
	End Function
	
	Private Function PrintSuccessMessage()
		Echo PrintHTMLHeader
		Dim Fn_HTML
		Fn_HTML = "<div class=""eline1""><font class=""success"">"& Lang_OrderPayedSuccess &"</font></div>"
        Fn_HTML = Fn_HTML &"<div class=""eline2"">"& Lang_PayTradeLogID &":"& out_trade_no &"</div>"
        Fn_HTML = Fn_HTML &"<div class=""eline3"">"& Lang_OrderID &":"& Pv_OrderID &"</div>"
        Fn_HTML = Fn_HTML &"<div class=""btnline""><a href="""& SiteURL & SystemPath &""" title=""Home"" target=""_self"">"& Lang_Client_Home &"</a><a href="""& SiteURL & SystemPath &"?myhome/order.htm"" target=""_self"">"& Lang_ViewMyOrder &"</a></div>"
		Echo Fn_HTML
		Echo PrintHTMLFooter
	End Function
	
	Private Function PrintFailMessage(ByVal BV_Message)
		Echo PrintHTMLHeader
		Dim Fn_HTML
		Fn_HTML = "<div class=""eline1""><font class=""fail"">"& Lang_OrderPayedFail &"</font></div>"
		If Not(KnifeCMS.Data.IsNul(BV_Message)) Then
		Fn_HTML = Fn_HTML &"<div class=""eline2"">"& BV_Message &"</div>"
		End If
        Fn_HTML = Fn_HTML &"<div class=""eline2"">"& Lang_PayTradeLogID &":"& out_trade_no &"</div>"
        Fn_HTML = Fn_HTML &"<div class=""eline3"">"& Lang_OrderID &":"& Pv_OrderID &"</div>"
        Fn_HTML = Fn_HTML &"<div class=""btnline""><a href="""& SiteURL & SystemPath &""" title=""Home"" target=""_self"">"& Lang_Client_Home &"</a><a href="""& SiteURL & SystemPath &"?myhome/order.htm"" target=""_self"">"& Lang_ViewMyOrder &"</a></div>"
		Echo Fn_HTML
		Echo PrintHTMLFooter
	End Function
	
'========================================================
' 类名：AlipaySubmit
' 功能：支付宝各接口请求提交类
' 详细：构造支付宝各接口表单HTML文本，获取远程HTTP数据
' 版本：3.3
' 修改日期：2012-07-13
' KnifeCMS集成
' 集成人：linx
' 集成时间：2012-12-30
	''
	' 生成签名结果
	' param sParaSort 待签名的数组
	' return 签名结果字符串
	Private Function BuildRequestMysign(sParaSort)
		Dim prestr
		'把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
		prestr = CreateLinkstring(sParaSort)
		
		'获得签名结果
		 Select Case sign_type
		 	Case "MD5" BuildRequestMysign = Md5Sign(prestr,key,input_charset)
			Case Else BuildRequestMysign = ""
		 End Select
	End Function

	''
	' 生成要请求给支付宝的参数数组
	' param sParaTemp 请求前的参数数组
	' return 要请求的参数数组
	Private Function BuildRequestPara(sParaTemp)
		Dim mysign,sPara,sParaSort,nCount
		'过滤签名参数数组
		sPara = FilterPara(sParaTemp)
		
		'对请求参数数组排序
		sParaSort = SortPara(sPara)
		
		'获得签名结果
		mysign = BuildRequestMysign(sParaSort)
		
		'签名结果与签名方式加入请求提交参数组中
		nCount = ubound(sParaSort)
		Redim Preserve sParaSort(nCount+1)
		sParaSort(nCount+1) = "sign="&mysign
		Redim Preserve sParaSort(nCount+2)
		sParaSort(nCount+2) = "sign_type="&sign_type

		BuildRequestPara = sParaSort
	End Function
	
	''
	' 生成要请求给支付宝的参数数组字符串
	' param sParaTemp 请求前的参数数组
	' return 要请求的参数数组字符串
	Private Function BuildRequestParaToString(sParaTemp)
		Dim sPara,sRequestData
		'待签名请求参数数组
		sPara = BuildRequestPara(sParaTemp)
		'把参数组中所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串，并且对其做urlencode编码处理
		sRequestData = CreateLinkStringUrlEncode(sPara)
		
		BuildRequestParaToString = sRequestData
	End Function

	''
	' 建立请求，以表单HTML形式构造（默认）
	' param sParaTemp 请求前的参数数组
	' param sMethod 提交方式。两个值可选：post、get
	' param sButtonValue 确认按钮显示文字
	' return 提交表单HTML文本
	Public Function BuildRequestForm(sParaTemp, sMethod, sButtonValue)
		Dim sPara,sHtml,nCount,i,iPos,nLen,sItemName,sItemValue
		'待请求参数数组
		sPara = BuildRequestPara(sParaTemp)
		
		sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='"& GATEWAY_NEW &"_input_charset="&input_charset&"' method='"&sMethod&"'>"
		
		nCount = ubound(sPara)
		For i = 0 To nCount
			'把sPara的数组里的元素格式：变量名=值，分割开来
			iPos = Instr(sPara(i),"=")			'获得=字符的位置
			nLen = Len(sPara(i))				'获得字符串长度
			sItemName = left(sPara(i),iPos-1)	'获得变量名
			sItemValue = right(sPara(i),nLen-iPos)'获得变量的值
		
			sHtml = sHtml & "<input type='hidden' name='"& sItemName &"' value='"& sItemValue &"'/>"
		next

		'submit按钮控件请不要含有name属性
		'submit按钮默认设置为不显示
		sHtml = sHtml & "<input type='submit' value='"&sButtonValue&"' style='display:none;'></form>"
		
		sHtml = sHtml & "<script>document.forms['alipaysubmit'].submit();</script>"
		
		BuildRequestForm = sHtml
	End Function
	
	''
	' 建立请求，以模拟远程HTTP的GET请求方式构造并获取支付宝XML类型处理结果
	' param sParaTemp 请求前的参数数组
	' param sParaNode 要输出的XML节点名
	' return 支付宝返回XML指定节点内容
	Public Function BuildRequestHttpXml(sParaTemp, sParaNode)
		Dim sRequestData,sUrl, objHttp, objXml, nCount, sParaXml()
		nCount = ubound(sParaNode)
		
		'待请求参数数组字符串
		sRequestData = BuildRequestParaToString(sParaTemp)
		'构造请求地址
		sUrl = GATEWAY_NEW & sRequestData

		'获取远程数据
		Set objHttp=Server.CreateObject("Microsoft.XMLHTTP")
		'如果Microsoft.XMLHTTP不行，那么请替换下面的两行行代码尝试
		'Set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
		'objHttp.setOption 2, 13056
		objHttp.open "GET", sUrl, False, "", ""
		objHttp.send()
		Set objXml=Server.CreateObject("Microsoft.XMLDOM")
		objXml.Async=true
		objXml.ValidateOnParse=False
		objXml.Load(objHttp.ResponseXML)
		Set objHttp = Nothing
		
		set objXmlData = objXml.getElementsByTagName("alipay").item(0)
		If Isnull(objXmlData.selectSingleNode("alipay")) Then
			Redim Preserve sParaXml(1)
			sParaXml(0) = "错误：非法XML格式数据"
		Else
			If objXmlData.selectSingleNode("is_success").text = "T" Then
				For i = 0 To nCount
					Redim Preserve sParaXml(i+1)
					sParaXml(i) = objXmlData.selectSingleNode(sParaNode(i)).text
				Next
			Else
				Redim Preserve sParaXml(1)
				sParaXml(0) = "错误："&objXmlData.selectSingleNode("error").text
			End If
		End If
		
		BuildRequestHttpXml = sParaXml
	End Function
	
	''
	' 建立请求，以模拟远程HTTP的GET请求方式构造并获取支付宝纯文字类型处理结果
	' param sParaTemp 请求前的参数数组
	' return 支付宝处理结果
	Public Function BuildRequestHttpWord(sParaTemp)
		Dim sRequestData,sUrl, objHttp, sResponseTxt
		
		'待请求参数数组字符串
		sRequestData = BuildRequestParaToString(sParaTemp)
		'构造请求地址
		sUrl = GATEWAY_NEW & sRequestData

		'获取远程数据
		Set objHttp=Server.CreateObject("Microsoft.XMLHTTP")
		'如果Microsoft.XMLHTTP不行，那么请替换下面的两行行代码尝试
		'Set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
		'objHttp.setOption 2, 13056
		objHttp.open "GET", sUrl, False, "", ""
		objHttp.send()
		sResponseTxt = objHttp.ResponseText
		Set objHttp = Nothing
		
		BuildRequestHttpWord = sResponseTxt
	End Function

	''
	' 用于防钓鱼，调用支付宝防钓鱼接口(query_timestamp)来获取时间戳的处理函数
	' 注意：远程解析XML出错，与IIS服务器配置有关
	' return 时间戳字符串
	Public Function Query_timestamp()
		Dim sUrl, encrypt_key
		sUrl = GATEWAY_NEW &"service=query_timestamp&partner="&partner
		encrypt_key = ""
		
		Dim objHttp, objXml
		Set objHttp=Server.CreateObject("Microsoft.XMLHTTP")
		'如果Microsoft.XMLHTTP不行，那么请替换下面的两行行代码尝试
		'Set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
		'objHttp.setOption 2, 13056
		objHttp.open "GET", sUrl, False, "", ""
		objHttp.send()
		Set objXml=Server.CreateObject("Microsoft.XMLDOM")
		objXml.Async=true
		objXml.ValidateOnParse=False
		objXml.Load(objHttp.ResponseXML)
		Set objHttp = Nothing
		
		Set objXmlData = objXml.getElementsByTagName("encrypt_key")  '节点的名称
		If Isnull(objXml.getElementsByTagName("encrypt_key")) Then
			encrypt_key = ""
		Else
			encrypt_key = objXmlData.item(0).childnodes(0).text
		End If

		Query_timestamp = encrypt_key
	End Function
'========================================================
'========================================================
' 类名：AlipayNotify
' 功能：支付宝通知处理类
' 详细：处理支付宝各接口通知返回
' 版本：3.3
' 修改日期：2012-07-16
' KnifeCMS集成
' 集成人：linx
' 集成时间：2012-12-30

	''
	' 针对return_url验证消息是否是支付宝发出的合法消息
	' return 验证结果：true/false
	Public Function VerifyReturn()
		Dim sParaTemp, mysign, sResponseTxt, url
		'获取支付宝GET过来通知消息，并以"参数名=参数值"的形式组成数组
		sParaTemp = GetRequestGet()
		
		'验证是否有数组传来
		If IsArray(sParaTemp) Then
			'生成签名结果
			mysign = GetSignVeryfy(sParaTemp)
			
			'获取支付宝远程服务器ATN结果（验证是否是支付宝发来的消息）
			sResponseTxt = "true"
			If Request.QueryString("notify_id") <> "" Then
				sResponseTxt = GetResponse(Request.QueryString("notify_id"))
			End If
			
			'写日志记录（若要调试，请取消下面两行注释）
			'sWord = "responseTxt="& sResponseTxt &"\n return_url_log:sign="&request.QueryString("sign")&"&mysign="&mysign&"&"&CreateLinkstring(sParaTemp)
			'LogResult(sWord)
			
			'验证
			'responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
			'mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
			If mysign = Request.QueryString("sign") And sResponseTxt = "true" Then
				VerifyReturn = true
			Else
				VerifyReturn = false
			End If
		Else
			VerifyReturn = false
		End If
	End Function

	''
	' 针对notify_url验证消息是否是支付宝发出的合法消息
	' return 验证结果：true/false
	Public Function VerifyNotify()
		Dim sParaTemp, mysign, sResponseTxt, url,sWord
		'获取支付宝POST过来通知消息，并以"参数名=参数值"的形式组成数组
		
		sParaTemp = GetRequestPost()
		
		'验证是否有数组传来
		If IsArray(sParaTemp) Then
			'生成签名结果
			mysign = GetSignVeryfy(sParaTemp)
			
			'获取支付宝远程服务器ATN结果（验证是否是支付宝发来的消息）
			sResponseTxt = "true"
			If Request.Form("notify_id") <> "" Then
				sResponseTxt = GetResponse(Request.Form("notify_id"))
			End If
			
			'写日志记录（若要调试，请取消下面两行注释）
			sWord = "responseTxt="& sResponseTxt &"\n notify_url_log:sign="&request.Form("sign")&"&mysign="&mysign&"&"&CreateLinkstring(sParaTemp)
			LogResult(sWord)
			
			'验证
			'responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
			'mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
			If mysign = request.Form("sign") And sResponseTxt = "true" Then
				VerifyNotify = true
			Else
				VerifyNotify = false
			End If
		Else
			VerifyNotify = false
		End If
	End Function

	''
	'根据反馈回来的信息，生成签名结果
	'param sParaTemp 通知返回来的参数数组
	'return 生成的签名结果
	Private Function GetSignVeryfy(sParaTemp)
		Dim sPara, mysign, sParaSort, prestr
		'过滤签名参数数组
		sPara = FilterPara(sParaTemp)
		
		'对请求参数数组排序
		sParaSort = SortPara(sPara)
		
		'把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
		prestr = CreateLinkstring(sParaSort)
		
		'获得签名结果
		 Select Case sign_type
		 	Case "MD5" GetSignVeryfy = Md5Sign(prestr, key, input_charset)
			Case Else GetSignVeryfy = ""
		 End Select
	End Function

	''
	' 获取远程服务器ATN结果
	' param notify_id 通知校验ID
	' return 服务器ATN结果字符串
	Private Function GetResponse(notify_id)
		Dim sUrl, objHttp, sResponseTxt

		sUrl = HTTPS_VERIFY_URL & "partner=" & partner & "&notify_id=" & notify_id
		
		Set objHttp = Server.CreateObject("Microsoft.XMLHTTP")
		'如果Microsoft.XMLHTTP不行，那么请替换下面的两行行代码尝试
		'Set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
		'objHttp.setOption 2, 13056
		objHttp.open "GET", sUrl, False, "", ""
		objHttp.send()
		sResponseTxt = objHttp.ResponseText
		Set objHttp = Nothing

		GetResponse = sResponseTxt
	End Function

	''
	'获取支付宝GET过来通知消息，并以"参数名=参数值"的形式组成数组
	'return request回来的信息组成的数组
	Private Function GetRequestGet()
		Dim sPara(), i, varItem
		i = 0
		For Each varItem in Request.QueryString
			Redim Preserve sPara(i)
			sPara(i) = varItem&"="&Request(varItem)
			i = i + 1
		Next 
		
		If i = 0 Then	'验证是否有数组传来
			GetRequestGet = ""
		Else
			GetRequestGet = sPara
		End If
		
	End Function

	''
	'获取支付宝POST过来通知消息，并以"参数名=参数值"的形式组成数组
	'return request回来的信息组成的数组
	Private Function GetRequestPost()
		Dim sPara(), i, varItem
		i = 0
		
		For Each varItem in Request.Form
			Redim Preserve sPara(i)
			sPara(i) = varItem&"="&Request(varItem) 
			i = i + 1
		Next 
		
		If i = 0 Then	'验证是否有数组传来
			GetRequestPost = ""
		Else
			GetRequestPost = sPara
		End If
	End Function
	
'========================================================

End Class

%>